home *** CD-ROM | disk | FTP | other *** search
- /**
- GRAB Graph Layout and Browser System
-
- Copyright (c) 1986, 1988 Regents of the University of California
- Copyright (c) 1989, Tera Computer Company
- **/
-
- /**
- routines for deletions
-
- The tricky parts of deletions mostly are due to dummy nodes. If
- an edge is deleted and one endpoint is a dummy node, the whole edge
- must be eliminated.
-
- If a node is deleted, all edges from it must be deleted.
-
- If a dummy node is deleted, simply 'straighten' the edge so that
- the dummy's previous node connects directly to the dummy's next node.
-
- Multiple edges are also a problem: If you delete a dummy node that
- handles multiple edges, all those edges must be straightened.
- If you delete an edge, you must check whether there is still an edge
- left between the two nodes, and if not, links and outedge must be
- removed.
- **/
-
- #include "digraph.h"
- #include "globals.h"
- #include "interf.h"
- #include "tedge.h"
-
- OUTEDGE *get_edge();
- NODE *DeleteFromDummyNodes(), *DeleteToDummyNodes();
-
- void DoSDeleteNode()
- /**
- Delete the node the cursor is pointing to.
-
- First, eliminate it from the screen.
- Then, delete it from the data structure.
- **/
- {
- NODE *node;
-
- if ((node = (NODE *) ICurNode()) == NULL)
- {
- IChangeStatusLine("No node under cursor", FALSE);
- return;
- }
-
- /* delete it from the screen */
- ScrDeleteNode(digraph, node);
-
- /* delete it from the digraph data structure */
- if (Is_dummy(node))
- {
- DeleteDummy(digraph, node);
- }
- else
- {
- DeleteNode(digraph, node);
- }
-
- IChangeStatusLine("Node Deleted", FALSE);
- graphChanged = TRUE;
- ckpt_done = FALSE;
- }
-
- void DoSDeleteArc()
- /**
- Delete the edge the cursor is pointing to
-
- First, eliminate it from the screen.
- Then, eliminate it from the digraph data structure.
- **/
- {
- NODE *top, *bot;
- NODE *from, *to;
- TEDGE *edge;
-
- edge = (TEDGE *) ICurEdge();
- from = (NODE *) edge->fromnode;
- to = (NODE *) edge->tonode;
-
- /* delete the edge from the screen */
- ScrDeleteEdge(digraph, from, to, edge->ord, &top, &bot);
-
- /* delete the edge from digraph */
- DeleteEdge(digraph, top, bot, edge->ord);
-
- IChangeStatusLine("Arc Deleted", FALSE);
- graphChanged = TRUE;
- ckpt_done = FALSE;
- }
-
- extern NODE *prev_dummy();
- extern NODE *next_dummy();
-
- DeleteDummy(digraph, node)
- DIGRAPH *digraph;
- NODE *node;
- /**
- To delete a dummy, 'straighten' the edge so it runs directly
- from the dummy's previous node to the dummy's next node. Of course,
- if the dummy had multiple edges, you must do it for all of them.
-
- The edges out of the dummy have already been deleted, so all that
- must be done is to add the edges, remove the old link, and add the
- proper link.
- **/
- {
- NODE *prev, *next, *prev_dummy(), *next_dummy();
- OUTEDGE *e;
- int i;
-
- prev = prev_dummy(digraph, node);
- next = next_dummy(digraph, node);
-
- for (i = max_edges(prev, next); i > 0; i--)
- {
- if ((e = get_edge(digraph, prev, next, i)) != NULL)
- {
- draw_edge (digraph, e, prev, next, i, &screen, TRUE);
- }
- }
-
- remove_link(prev, node);
- remove_link(node, next);
-
- if (prev != next)
- /**
- I don't believe this will ever be false.
- That would imply an edge from a node to itself
- **/
- {
- add_element(Succ_set(prev), Vno(next));
- add_element(Ante_set(next), Vno(prev));
- }
-
- dispose_node(digraph, node);
- }
-
- NODE *get_next_node();
- NODE *prev_dummy(), *next_dummy();
-
- ScrDeleteNode(digraph, node)
- DIGRAPH *digraph;
- NODE *node;
- /* ScrDeleteNode removes a node from the screen, including all edges */
- {
- VNO prev_vno, next_vno;
- NODE *dummy, *prevnode, *nextnode;
- int i;
-
- if (Is_dummy(node))
- /* just remove edges out of the node */
- {
- each_element(Ante_set(node), prev_vno)
- loop
- prevnode = Node(digraph, prev_vno);
-
- for (i = max_edges(prevnode, node); i > 0; i--)
- {
- if (get_edge(digraph, prevnode, node, i) != NULL)
- {
- IDelEdge((char *) prevnode, (char *) node, i);
- }
- }
- endloop
-
- each_element(Succ_set(node), next_vno)
- loop
- nextnode = Node(digraph, prev_vno);
-
- for (i = max_edges(node, nextnode); i > 0; i--)
- {
- if (get_edge(digraph, node, nextnode, i) != NULL)
- {
- IDelEdge((char *) node, (char *) nextnode, i);
- }
- }
- endloop
- }
- else
- /**
- remove ancestor dummy nodes and edges.
- remove successor dummy nodes and edges.
- **/
- {
- each_element(Ante_set(node), prev_vno)
- loop
- prevnode = Node(digraph, prev_vno);
-
- for (i = max_edges(prevnode, node); i > 0; i--)
- {
- if (get_edge(digraph, prevnode, node, i) != NULL)
- {
- scr_remove_ante_links(digraph, node, prevnode, i, &dummy);
- }
- }
- endloop
-
- each_element(Succ_set(node), next_vno)
- loop
- nextnode = Node(digraph, next_vno);
-
- for (i = max_edges(node, nextnode); i > 0; i--)
- {
- if (get_edge(digraph, node, nextnode, i) != NULL)
- {
- scr_remove_succ_links(digraph, node, nextnode, i, &dummy);
- }
- }
- endloop
- }
-
- IDelNode((char *) node, -1); /* erase node from screen */
- } /* ScrDeleteNode */
-
- ScrDeleteEdge(digraph, from_node, to_node, ord, top, bot)
- DIGRAPH *digraph;
- NODE *from_node, *to_node;
- int ord;
- NODE **top, **bot;
- /**
- remove ancestor dummy nodes and edges
- remove successor dummy nodes and edges
- return the endpoints of the edge in top and bot
- **/
- {
- /* this also removes the current edge */
- scr_remove_ante_links (digraph, to_node, from_node, ord, top);
-
- if (Is_dummy(to_node))
- {
- scr_remove_succ_links (digraph, to_node, next_dummy(digraph, to_node),
- ord, bot);
- IDelNode((char *) to_node, ord);
- }
- else
- {
- *bot = to_node;
- }
- } /* ScrDeleteEdge */
-
- scr_remove_ante_links(digraph, node, prev_node, ord, top)
- DIGRAPH *digraph;
- NODE *node, *prev_node;
- int ord;
- NODE **top;
- /**
- scr_remove_ante_links follows the chain of ancestor edges from node
- through prev through the prev non-dummy node, deleting all edges and
- dummy nodes along the way. When done, it sets top to the prev non-dummy
- node.
- **/
- {
- NODE *curr, *prev;
-
- IDelEdge((char *) prev_node, (char *) node, ord);
- curr = prev_node;
-
- while (Is_dummy(curr))
- {
- prev = prev_dummy(digraph, curr);
- IDelEdge((char *) prev, (char *) curr, ord);
- IDelNode((char *) curr, ord);
- curr = prev;
- }
-
- *top = curr;
- } /* scr_remove_ante_links */
-
- scr_remove_succ_links(digraph, node, next_node, ord, bot)
- DIGRAPH *digraph;
- NODE *node, *next_node;
- int ord;
- NODE **bot;
- /**
- scr_remove_succ_links follows the chain of successor edges from node
- through next through the next non-dummy node, deleting all edges and
- dummy nodes along the way. When done, it sets bot to the next non-dummy
- node.
- **/
- {
- NODE *curr, *next;
-
- IDelEdge((char *) node, (char *) next_node, ord);
- curr = next_node;
-
- while (Is_dummy(curr))
- {
- next = next_dummy(digraph, curr);
- IDelEdge((char *) curr, (char *) next, ord);
- IDelNode((char *) curr, ord);
- curr = next;
- }
-
- *bot = curr;
- } /* scr_remove_succ_links */
-